package com.miniapp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.miniapp.entity.enums.UserStatus;
import com.miniapp.entity.MiniUserEntity;
import com.miniapp.entity.enums.UserType;
import com.miniapp.mapper.MiniUserMapper;
import com.miniapp.service.MiniUserService;
import com.miniapp.utils.BCrypt;
import com.miniapp.utils.BaseUtils;
import com.miniapp.utils.R;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;


/**
 * 系统用户
 * 
 * @author linyuchi
 * @date 2018/03/18
 */
@Service
public class MiniUserServiceImpl extends BaseServiceImpl<MiniUserMapper,MiniUserEntity> implements MiniUserService {



    @Override
    public MiniUserEntity findByUserName(String username) {
        return baseMapper.selectOne(new QueryWrapper<MiniUserEntity>().eq("username",username));
    }

    @Override
    public boolean updatePassword(Long userId, String password, String newPassword) {
        MiniUserEntity userEntity = baseMapper.selectById(userId);
        if (!password.equals(userEntity.getPassword())){
            return false;
        }
        userEntity.setPassword(newPassword);
        try{
            baseMapper.insert(userEntity);
        }catch (Exception e){
            return false;
        }
        return true;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public R saveUser(MiniUserEntity user) {

        MiniUserEntity userEntity;
        if (BaseUtils.isNotEmpty(user.getId())){
            userEntity = baseMapper.selectById(user.getId());
        }else {
            userEntity = new MiniUserEntity();
            if (BaseUtils.isEmpty(user.getRebate())){
                userEntity.setRebate(BigDecimal.ONE);
            }else {
                userEntity.setRebate(user.getRebate());
            }
            if (BaseUtils.isEmpty(user.getBalance())){
                userEntity.setBalance(BigDecimal.ONE);
                userEntity.setBalanceEncrypt(encryptionMoney(BigDecimal.ZERO));
            }else {
                userEntity.setBalance(user.getBalance());
                userEntity.setBalanceEncrypt(encryptionMoney(user.getBalance()));
            }
            if (BaseUtils.isEmpty(user.getTotal())){
                userEntity.setTotal(BigDecimal.ONE);
            }else {
                userEntity.setTotal(user.getTotal());
            }
        }

        userEntity.setUsername(user.getUsername());
        if (BaseUtils.isNotEmpty(user.getCreateUserId())){
            userEntity.setCreateUserId(user.getCreateUserId());
        }

        userEntity.setEmail(user.getEmail());
        if (BaseUtils.isEmpty(user.getStatus())){
            userEntity.setStatus(UserStatus.ACTIVE);
        }else {
            userEntity.setStatus(user.getStatus());
        }
        userEntity.setMobile(user.getMobile());
        userEntity.setName(user.getName());

        userEntity.setUserType(BaseUtils.isNotEmpty(user.getUserType())? UserType.COMMON.getValue():user.getUserType());

        if(BaseUtils.isNotEmpty(user.getParentUserId())){
            userEntity.setParentUserId(user.getParentUserId());
        }
        userEntity.setUserType(UserType.COMMON.getValue());
        if (BaseUtils.isNotEmpty(user.getPassword())){
            //sha256加密
            String salt = RandomStringUtils.randomAlphanumeric(20);
            userEntity.setPassword(new Sha256Hash(user.getPassword(), salt).toHex());
            userEntity.setSalt(salt);
        }

        this.saveOrUpdate(userEntity);
        return R.ok();
    }

    /**
     * 变更用户金额
     * @param adminId
     * @param id
     * @param addMoney
     * @return
     */
    @Override
    public R
    updateBalance(Long adminId, Long id, BigDecimal addMoney) {

        MiniUserEntity entity = baseMapper.selectById(id);
        if (!this.checkEncrptionMoney(entity.getBalance(),entity.getBalanceEncrypt())){
            return R.error("金额校验失败！");
        }
        BigDecimal balance = BaseUtils.formatBigDecimalM2(addMoney.add(entity.getBalance()));

        entity.setBalance(balance);
        entity.setBalanceEncrypt(this.encryptionMoney(balance));
        baseMapper.updateById(entity);
        return R.ok();
    }

    /**
     * 用户注册验证手机号码是否存在
     * @param mobile 手机号码
     * @return 存在返回 true
     */
    @Override
    public boolean isMobileExist(String mobile) {
        Boolean isMobileExist = false;
        MiniUserEntity user = baseMapper.selectOne(new QueryWrapper<MiniUserEntity>().eq("mobile",mobile));
        if (null != user) {
            isMobileExist = true;
        }
        return isMobileExist;
    }

    @Override
    public boolean checkPassword(MiniUserEntity user, String oldPassword) {

        if (oldPassword.equals(new  Sha256Hash(user.getPassword(), user.getSalt()).toHex())){
            return true;
        }
        return false;
    }

    /**
     * 转换金额为用于加密的纯字符串（主要统一设置精度为2，避免1.0和1.00出现不一样的加密结果）
     * @param money 金额
     * @return 用于加密的纯字符串
     */
    private String tranMoneyToPlainString(BigDecimal money) {
        BigDecimal scaleValue = BigDecimal.valueOf(money.doubleValue()).setScale(2);
        return scaleValue.toString();
    }
    /**
     * 加密金额
     * @param money 金额
     * @return 加密后的字符串
     */
    @Override
    public String encryptionMoney(BigDecimal money) {
        return BCrypt.hash(tranMoneyToPlainString(money));
    }

    /**
     * 检测金额是否合法
     * @param money 待检测金额
     * @param checkHashText 加密后的串
     * @return 是否合法
     */
    @Override
    public Boolean checkEncrptionMoney(BigDecimal money, String checkHashText) {
        String moneyPlainText = tranMoneyToPlainString(money);
        return BCrypt.checkHash(moneyPlainText, checkHashText);
    }


}
